const fs = require('fs-extra');
const path = require('path');
const VueFileParser = require('../parsers/vueFileParser');
const Logger = require('../utils/logger');

/**
 * Vue 文件分析器
 * 负责扫描目录、分析 Vue 文件并生成统计信息
 */
class VueFileAnalyzer {
  constructor() {
    this.parser = new VueFileParser();
    this.stats = {
      totalFiles: 0,
      totalLines: 0,
      templateLines: 0,
      scriptLines: 0,
      styleLines: 0,
      maxFile: null,
      minFile: null,
      errors: [],
      avgLines: 0,
      avgTemplateLines: 0,
      avgScriptLines: 0,
      avgStyleLines: 0
    };
  }

  /**
   * 分析指定目录下的 Vue 文件
   * @param {string} directory - 要分析的目录路径
   * @param {Object} options - 分析选项
   * @returns {Promise<Object>} 分析结果
   */
  async analyzeDirectory(directory, options = {}) {
    try {
      // 检查目录是否存在
      if (!await fs.pathExists(directory)) {
        throw new Error(`目录不存在: ${directory}`);
      }

      // 设置基准目录用于计算相对路径
      this.baseDirectory = path.resolve(directory);

      Logger.info(`开始分析目录: ${directory}`);

      // 获取所有 Vue 文件
      const vueFiles = await this.getVueFiles(directory, options.recursive !== false);

      if (vueFiles.length === 0) {
        Logger.warning('未找到任何 .vue 文件');
        return { files: [], stats: this.stats };
      }

      Logger.info(`找到 ${vueFiles.length} 个 .vue 文件，开始分析...`);

      // 并行分析所有文件
      const fileResults = await this.analyzeFiles(vueFiles, options);

      // 计算统计信息
      this.calculateStats(fileResults);

      Logger.success(`分析完成，共处理 ${fileResults.length} 个文件`);

      return {
        directory: this.baseDirectory,
        files: fileResults,
        stats: this.stats
      };
    } catch (error) {
      Logger.error(`分析目录失败: ${error.message}`);
      throw error;
    }
  }

  /**
   * 递归获取目录下所有 Vue 文件
   * @param {string} directory - 目录路径
   * @param {boolean} recursive - 是否递归扫描
   * @returns {Promise<string[]>} Vue 文件路径数组
   */
  async getVueFiles(directory, recursive = true) {
    const vueFiles = [];

    const scan = async (dir) => {
      const items = await fs.readdir(dir);

      for (const item of items) {
        const fullPath = path.join(dir, item);
        const stat = await fs.stat(fullPath);

        if (stat.isDirectory() && recursive) {
          // 跳过常见的不需要扫描的目录
          if (!['node_modules', '.git', '.vscode', 'dist', 'build'].includes(item)) {
            await scan(fullPath);
          }
        } else if (stat.isFile() && item.endsWith('.vue')) {
          vueFiles.push(fullPath);
        }
      }
    };

    await scan(directory);
    return vueFiles;
  }

  /**
   * 并行分析多个 Vue 文件
   * @param {string[]} filePaths - 文件路径数组
   * @param {Object} options - 分析选项
   * @returns {Promise<Array>} 文件分析结果数组
   */
  async analyzeFiles(filePaths, options) {
    const results = [];

    // 分批处理，避免同时打开太多文件
    const batchSize = 10;
    for (let i = 0; i < filePaths.length; i += batchSize) {
      const batch = filePaths.slice(i, i + batchSize);
      const batchResults = await Promise.allSettled(
        batch.map(filePath => this.analyzeFile(filePath, options))
      );

      // 处理批次结果
      batchResults.forEach((result, index) => {
        if (result.status === 'fulfilled') {
          results.push(result.value);
        } else {
          const filePath = batch[index];
          Logger.warning(`解析文件失败: ${filePath} - ${result.reason.message}`);
          this.stats.errors.push({
            file: filePath,
            error: result.reason.message
          });
        }
      });
    }

    return results;
  }

  /**
   * 分析单个 Vue 文件
   * @param {string} filePath - 文件路径
   * @param {Object} options - 分析选项
   * @returns {Promise<Object>} 文件分析结果
   */
  async analyzeFile(filePath, options) {
    try {
      const content = await fs.readFile(filePath, 'utf-8');
      const relativePath = path.relative(this.baseDirectory || process.cwd(), filePath);

      // 解析文件内容
      const analysis = await this.parser.parse(content, options);

      return {
        filePath,
        relativePath,
        fileName: path.basename(filePath),
        directory: path.dirname(relativePath),
        ...analysis
      };
    } catch (error) {
      throw new Error(`解析文件 ${filePath} 失败: ${error.message}`);
    }
  }

  /**
   * 计算统计信息
   * @param {Array} fileResults - 文件分析结果数组
   */
  calculateStats(fileResults) {
    if (fileResults.length === 0) return;

    this.stats.totalFiles = fileResults.length;
    this.stats.totalLines = fileResults.reduce((sum, file) => sum + file.totalLines, 0);
    this.stats.templateLines = fileResults.reduce((sum, file) => sum + file.templateLines, 0);
    this.stats.scriptLines = fileResults.reduce((sum, file) => sum + file.scriptLines, 0);
    this.stats.styleLines = fileResults.reduce((sum, file) => sum + file.styleLines, 0);

    // 查找最大和最小文件
    const sortedFiles = fileResults.sort((a, b) => b.totalLines - a.totalLines);
    this.stats.maxFile = sortedFiles[0];
    this.stats.minFile = sortedFiles[sortedFiles.length - 1];

    // 计算平均值
    this.stats.avgLines = Math.round(this.stats.totalLines / this.stats.totalFiles * 10) / 10;
    this.stats.avgTemplateLines = Math.round(this.stats.templateLines / this.stats.totalFiles * 10) / 10;
    this.stats.avgScriptLines = Math.round(this.stats.scriptLines / this.stats.totalFiles * 10) / 10;
    this.stats.avgStyleLines = Math.round(this.stats.styleLines / this.stats.totalFiles * 10) / 10;
  }
}

module.exports = VueFileAnalyzer;